#include <stdio.h>
#include <string.h>
#include <vxWorks.h>
#include <sockLib.h>
#include <inetLib.h>
#include <taskLib.h>
#include <ioLib.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <cacheLib.h>
#include "tcp_server.h"
#include "icd.h"
extern unsigned int get_fpga_slot_number(); 
extern void clear_group_state(unsigned char group);
extern void config_self_test(unsigned char group, unsigned char enable);
extern void config_sample_dur(unsigned char group, unsigned int duration);
extern void config_edge_trigger(unsigned char group, unsigned char edge_pin, unsigned char enable, unsigned char rise_fall);
extern unsigned char is_group_finish(unsigned char group);
static uint32_t data_size = 0;  // 全局变量，用于存储数据量;

// 全局服务器实例
TcpServer g_server;

static uint32_t * sample_buffer_addr[20];  // 定义一个全局变量来存储地址
extern  void set_buffer_address(unsigned char group, unsigned int buffer_addr);
extern void syncControlAllGroups(unsigned char enable) ;
extern unsigned char is_group_enabled(unsigned char group);
extern void set_sample_duration(unsigned char group, unsigned int sample_duration) ;
extern void enable_group(unsigned char group, unsigned char enable) ;

// 全局变量，用于保存数据发送任务 ID
WIND_TCB* g_data_transfer_task_id = NULL;
// 数据包有效数据最大字节数限制为1000字节
#define MAX_PACKET_DATA_SIZE 1000
// 数据包实际数据区大小为1000字节 (符合ICD协议)
#define ICD_PACKET_DATA_SIZE 1000
// 假设 DataTransferResponse 结构体中 data 数组大小
#define PACKET_DATA_SIZE sizeof(((DataTransferResponse *)0)->data)
STATUS process_handshake(int sockfd, IcdPacket* packet);
STATUS process_mode_set(int sockfd, IcdPacket* packet);
STATUS process_status_query(int sockfd, IcdPacket* packet);
STATUS process_data_transfer(int sockfd, IcdPacket* packet);

// 协议握手处理函数
STATUS process_handshake(int sockfd, IcdPacket* packet) {

    // 构造握手响应
    HandResponse resp = {0};
    resp.header_flag = 0x5AA55AA5;
    resp.command_type = ICD_HANDSHAKE;
    // 获取槽位号并填充到物理地址
    uint8_t slot_number = get_fpga_slot_number();
    resp.zynq_phy_addr = slot_number;

    resp.tail_flag = 0xADDEADDE;
    send(sockfd, &resp, sizeof(resp), 0);
    return OK;
}



// 模式设置处理函数
STATUS process_mode_set(int sockfd, IcdPacket* packet) {
    int i,j;
    // 构造模式设置响应
    ModeSetResponse resp = {0};
    resp.header_flag = 0x5AA55AA5;
    resp.command_type = ICD_MODE_SET;
    resp.tail_flag = 0xADDEADDE;


    clear_group_state(0xFF);  // 清除所有20个采集组的完成状态
    // 获取槽位号并填充到物理地址
    uint8_t slot_number = get_fpga_slot_number();
    resp.zynq_phy_addr = slot_number;


    uint8_t time  = packet->payload[2];
    uint8_t freq  = packet->payload[3]; 
    resp.zynq_sample_duration = time;
    resp.zynq_sample_freq = freq;

    // 计算采样时长，为简化计算，提前将频率MHz转化
    uint32_t sampling_duration_s = 200 +  100*time;
    // 计算数据量（单位：字节）
    data_size = (uint32_t)(sampling_duration_s * 2 * 40 * 1000);

    logMsg("Calculated data size: %u bytes\n", data_size, 0, 0, 0, 0, 0);

    // 假设 sample_buffer_addr 是一个包含20个指针的数组
    for (i = 0; i < 20; i++) {

        uint8_t group_byte = packet->payload[4 + i/4];  // 每组4位，所以每字节包含4个组的信息
        logMsg("Payload byte for group %d: 0x%02x\n", i, group_byte, 0, 0, 0, 0);
        uint8_t group_bit = i % 4;
        uint8_t is_enabled = (group_byte >> (group_bit * 2 + 1)) & 0x01;  // 采集使能位
        uint8_t mode = (group_byte >> (group_bit * 2)) & 0x01;    // 采集模式位

        if (!is_enabled) {
            logMsg("Group %d is disabled, skip configuration\n", i, 0, 0, 0, 0, 0);
            enable_group(i, 0);

            continue;  // 组不采集，跳过
        }
        
        // 新增边沿触发配置解析（接在组使能判断之后）
        if (is_enabled) {
        // 判断第2个payload最低位，决定是否配置自测试
        if (packet->payload[1] & 0x01) {
            // 调用自测试配置函数
            config_self_test(i, 1);
            logMsg("Self-test configuration enabled.\n", 0, 0, 0, 0, 0, 0);
        }
        else
        {
            config_self_test(i, 0);
            logMsg("Self-test configuration disabled.\n", 0, 0, 0, 0, 0, 0);
        }  
        config_sample_dur(i, sampling_duration_s *  40 * 1000);
        // 从第15字节开始，每个组对应1字节配置（组0对应索引14，组1对应索引15...）
        uint8_t edge_cfg = packet->payload[9 + i];  // payload[14]对应组0
        logMsg("Group %d edge config: 0x%02x\n", i, edge_cfg, 0, 0, 0, 0);
        // 解析高4位为边沿管脚（0-11）
        unsigned char edge_pin = (edge_cfg >> 4) & 0x0F;
        if(edge_pin > 11) {
            logMsg("Group %d edge pin out of range: %d\n", i, edge_pin, 0, 0, 0, 0);
            edge_pin = 0;  // 使用默认管脚
        }

        // 解析bit3为边沿类型（1=上升沿，0=下降沿）
        unsigned char rise_fall = (edge_cfg >> 3) & 0x01;

        // 调用配置函数（参数顺序：group, edge_pin, enable, rise_fall）
        if(mode == 0)     
        	config_edge_trigger(i, edge_pin, 1, rise_fall);
        else
        	config_edge_trigger(i, edge_pin, 0, rise_fall);
        logMsg("Group %d edge config: pin=%d type=%s\n", 
                i, edge_pin, rise_fall ? "rising" : "falling", 0, 0, 0);
        }
        logMsg("Group %d is enabled, mode: %d\n", i, mode, 0, 0, 0, 0);              
        if (sample_buffer_addr[i] != NULL) { // 检查是否已分配内存
            free(sample_buffer_addr[i]); // 释放已有内存
        }
        sample_buffer_addr[i] = (uint32_t *)memalign(0x1000, data_size); // 分配内存
        if (sample_buffer_addr[i] == NULL) { // 检查是否分配成功
             logMsg("Memory allocation failed, index: %d\n", i, 0, 0, 0, 0, 0);
            // Free the already allocated memory
            for (j = 0; j < i; j++) {
                if (sample_buffer_addr[j] != NULL) {
                    free(sample_buffer_addr[j]);
                }
            }
            resp.status = 0xFF; 
            send(sockfd, &resp, sizeof(resp), 0);
            return ERROR; // 分配失败，返回错误
        }
         PHYS_ADDR    physicalAddr;
         if(vmTranslate (NULL,(VIRT_ADDR) sample_buffer_addr[i], &physicalAddr) == ERROR) {
             for (j = 0; j <= i; j++) {
                 if (sample_buffer_addr[j] != NULL) {
                     free(sample_buffer_addr[j]);
                 }
             }
            logMsg("vmTranslate failed for index %d, virtual address: 0x%x, free all allocated memory\n", i, (unsigned int)physicalAddr, 0, 0, 0, 0);
		  resp.status = 0xFF; 
		  send(sockfd, &resp, sizeof(resp), 0);
		  return ERROR; // 分配失败，返回错误
		}
		  else {
			 logMsg("vmTranslate success for index %d, virtual address: 0x%x, physical address: 0x%x\n", i, (unsigned int)sample_buffer_addr[i], (unsigned int)physicalAddr,  0, 0, 0);
			 set_buffer_address(i, (unsigned int)physicalAddr);
			 set_sample_duration(i, 200*40000*(time + 1));
			 enable_group(i,1); 
		  }
	  }



    resp.status = 0x0;  
    send(sockfd, &resp, sizeof(resp), 0);
    logMsg("Mode set response sent successfully.\n", 0, 0, 0, 0, 0, 0);
    return OK;
}

// 状态查询处理函数
STATUS process_status_query(int sockfd, IcdPacket* packet) {
    uint8_t val = 0;
    // 构造状态查询响应
    StatusQueryResponse resp = {0};
    resp.header_flag = 0x5AA55AA5;
    resp.command_type = ICD_ACQ_CTRL;
    resp.tail_flag = 0xADDEADDE;

    // 获取槽位号并填充到物理地址
    uint8_t slot_number = get_fpga_slot_number();
    resp.zynq_phy_addr = slot_number;
    uint8_t mode  = packet->payload[1] & 0xf; 
    if(mode == 0xf)
        syncControlAllGroups(1);
    else
        syncControlAllGroups(0);
    
    val = ((is_group_enabled(3) << 7) | (is_group_enabled(2) << 6) | (is_group_enabled(1) << 5) | (is_group_enabled(0) << 4)) | mode;
    resp.zynq_channel_status[0] =  val;
    logMsg("zynq_channel_status[0] set to 0x%02x\n", val, 0, 0, 0, 0, 0);
    
    val = (is_group_enabled(11) << 7)   | (is_group_enabled(10) << 6) | (is_group_enabled(9) << 5) | (is_group_enabled(8) << 4) | (is_group_enabled(7) << 3) | (is_group_enabled(6) << 2) | (is_group_enabled(5) << 1) | (is_group_enabled(4) << 0) ; 
    resp.zynq_channel_status[1] =  val;
    logMsg("zynq_channel_status[1] set to 0x%02x\n", val, 0, 0, 0, 0, 0);

    val = (is_group_enabled(19) << 7) | (is_group_enabled(18) << 6) | (is_group_enabled(17) << 5) | (is_group_enabled(16) << 4) | (is_group_enabled(15) << 3) | (is_group_enabled(14) << 2) | (is_group_enabled(13) << 1) | (is_group_enabled(12) << 0) ;                    
    resp.zynq_channel_status[2] =  val;
    logMsg("zynq_channel_status[2] set to 0x%02x\n", val, 0, 0, 0, 0, 0);



    // 填充组完成状态 - 参考zynq_channel_status的配置方式
    val = (is_group_finish(3) << 7) | (is_group_finish(2) << 6) | (is_group_finish(1) << 5) | (is_group_finish(0) << 4);
    resp.zynq_channel_completestatus[0] = val;
    logMsg("zynq_channel_completestatus[0] set to 0x%02x\n", val, 0, 0, 0, 0, 0);

    val = (is_group_finish(11) << 7) | (is_group_finish(10) << 6) | (is_group_finish(9) << 5) | (is_group_finish(8) << 4) | (is_group_finish(7) << 3) | (is_group_finish(6) << 2) | (is_group_finish(5) << 1) | (is_group_finish(4) << 0);
    resp.zynq_channel_completestatus[1] = val;
    logMsg("zynq_channel_completestatus[1] set to 0x%02x\n", val, 0, 0, 0, 0, 0);
    
    val = (is_group_finish(19) << 7) | (is_group_finish(18) << 6) | (is_group_finish(17) << 5) | (is_group_finish(16) << 4) | (is_group_finish(15) << 3) | (is_group_finish(14) << 2) | (is_group_finish(13) << 1) | (is_group_finish(12) << 0);
    resp.zynq_channel_completestatus[2] = val;
    logMsg("zynq_channel_completestatus[2] set to 0x%02x\n", val, 0, 0, 0, 0, 0);

    send(sockfd, &resp, sizeof(resp), 0);
    return OK;
}


static void send_data_packets(int sockfd, uint32_t group_enable_bits) {
    uint32_t packet_index = 0;
    int i;
    // 获取槽位号并填充到物理地址
    uint8_t slot_number = get_fpga_slot_number();
    
    for (i = 0; i < 20; ++i) {
        // 检查当前组是否被使能
        if (!(group_enable_bits & (1U << i))) {
            continue;  // 组未使能，跳过
        }
        
        if (sample_buffer_addr[i] == NULL) {
            logMsg("Group %d buffer is NULL\n", i, 0, 0, 0, 0, 0);
            continue;
        }     
        
        // 使用1000字节限制计算包数
        uint32_t total_packets = (data_size + MAX_PACKET_DATA_SIZE - 1) / MAX_PACKET_DATA_SIZE;        
        printf("Start sending data for group %d, total packets %d (data_size=%u, max_per_packet=%d)\n", 
               i, total_packets, data_size, MAX_PACKET_DATA_SIZE);

        uint32_t packet_index = 0;
        uint8_t *current_data_ptr = (uint8_t *)sample_buffer_addr[i];
        CACHE_USER_INVALIDATE(current_data_ptr, data_size);
        while (packet_index < total_packets) {
            DataTransferResponse resp = {0};
            // 按照ICD协议设置包头（小端序）
            resp.header_flag = 0x5AA55AA5;  // 会自动转换为小端序
            resp.command_type = ICD_DATA_TRANSFER;
            resp.zynq_phy_addr = slot_number;
            resp.zynq_sample_status = 0;  // 备份字段
            resp.channel = i;
            
            // 确保32位字段按小端序发送
            resp.packets_num = total_packets;    // VxWorks默认小端序
            resp.packet_index = packet_index;    // VxWorks默认小端序

            // 计算当前包的有效数据长度，最大为1000字节
            uint32_t remaining_data = data_size - packet_index * MAX_PACKET_DATA_SIZE;
            uint32_t packet_valid_len = (remaining_data < MAX_PACKET_DATA_SIZE) ? remaining_data : MAX_PACKET_DATA_SIZE;

            // 确保不超过data数组的实际大小（1000字节）
            if (packet_valid_len > PACKET_DATA_SIZE) {
                packet_valid_len = PACKET_DATA_SIZE;
            }
            
            resp.packet_valid_len = packet_valid_len;  // VxWorks默认小端序

            // 填充数据，使用1000字节边界计算偏移
            memcpy(resp.data, current_data_ptr + packet_index * MAX_PACKET_DATA_SIZE, packet_valid_len);

            // 设置包尾（小端序）
            resp.tail_flag = 0xADDEADDE;

            if (send(sockfd, &resp, sizeof(DataTransferResponse), 0) == -1) {
                perror("发送数据失败");
                break;
            }
            packet_index++;
        }
    }
   
    g_data_transfer_task_id = NULL;
}

// 数据传输处理函数
STATUS process_data_transfer(int sockfd, IcdPacket* packet) {
    if (packet->payload[1] == 0xff) { // 收到开始传输指令
    	int i;
        uint32_t group_enable_bits = 0;
        // 解析payload[2] - 对应组0-7
        group_enable_bits |= (uint32_t)packet->payload[2];
        // 解析payload[3] - 对应组8-15
        group_enable_bits |= (uint32_t)packet->payload[3] << 8;
        // 解析payload[4] - 对应组16-19 (只使用低4位)
        group_enable_bits |= ((uint32_t)packet->payload[4] & 0x0F) << 16;

        // 打印使能组信息
        for( i = 0; i < 20; i++) {
            if(group_enable_bits & (1U << i)) {
                logMsg("Group %d is enabled\n", i, 0, 0, 0, 0, 0);
            }
        }


        if (g_data_transfer_task_id == NULL) {
            g_data_transfer_task_id = (WIND_TCB*)taskSpawn("data_transfer_task", 100, VX_FP_TASK, 8192, 
                                                         (FUNCPTR)send_data_packets, sockfd, group_enable_bits, 0, 0, 0, 0, 0, 0, 0, 0);
            if (g_data_transfer_task_id == NULL) {
                perror("Failed to create data transfer task");
                return ERROR;
            }
        }
    } else if (packet->payload[1] == 0x00) { // 收到停止传输指令
        if (g_data_transfer_task_id != NULL) {
            printf("Stopping data transfer task...\n");
            taskDelete((TASK_ID)g_data_transfer_task_id);
            g_data_transfer_task_id = NULL;
            printf("Data transfer task stopped.\n");
        }
    }
    return OK;
}


void process_command(int sockfd, IcdPacket* packet) { 

    // 根据命令类型分发处理
    logMsg("command: %d\n", packet->command_type, 0, 0, 0, 0, 0);  // 打印收到的指令类型
    switch(packet->command_type) {
    case ICD_HANDSHAKE:
        logMsg("处理握手指令\n", 0, 0, 0, 0, 0, 0);
        process_handshake(sockfd, (IcdPacket*)packet);
        break;
    case ICD_MODE_SET: {
        logMsg("处理模式设置指令\n", 0, 0, 0, 0, 0, 0);
        process_mode_set(sockfd, (IcdPacket*)packet);
        break;
    }
    case ICD_ACQ_CTRL: {
        logMsg("处理状态查询指令\n", 0, 0, 0, 0, 0, 0);
        process_status_query(sockfd, (IcdPacket*)packet);
        break;
    }
    case ICD_DATA_TRANSFER: {
        logMsg("处理数据传输指令\n", 0, 0, 0, 0, 0, 0);
        process_data_transfer(sockfd, (IcdPacket*)packet);
        break;
    }
    default:
        logMsg("Unknown command type: %d\n", ntohs(packet->command_type), 0, 0, 0, 0, 0);
        break;
    }
}

// 客户端处理任务
void client_handler(int sockfd) {
    IcdPacket packet;
    int i;
    while (g_server.is_running) {
        // 接收协议头
        int n = recv(sockfd, &packet, sizeof(packet), MSG_WAITALL);
        if(n <= 0) break;
        // 打印接收到的数据长度
        printf("Received %d bytes of data.\n", n);
        // 打印接收到数据的前十个字节
        printf("Received data (first 10 bytes): ");
        for (i = 0; i < (n < 10 ? n : 10); i++) {
            printf("%x ", ((unsigned char*)&packet)[i]);
        }
        printf("\n");
        // 检查接收到的数据长度是否完整
        if(n < sizeof(IcdPacket)) {
            printf("数据包不完整，期望长度:%d，实际长度:%d\n", sizeof(IcdPacket), n);
            continue;
        }
        // 校验同步头
        if(packet.header_flag != 0x5AA55AA5) {
            printf("协议头错误\n");
            continue;
        }
         
        // 处理命令
        process_command(sockfd, &packet);
    }
    close(sockfd);
}

// 启动TCP服务器
STATUS tcp_server_start(unsigned short port) 
{
    struct sockaddr_in addr = {
        .sin_family = AF_INET,
        .sin_port = htons(port),
        .sin_addr.s_addr = INADDR_ANY
    };

    // 创建服务器socket
    if ((g_server.server_fd = socket(AF_INET, SOCK_STREAM, 0)) == ERROR) {
        perror("socket创建失败");
        return ERROR;
    }

    // 绑定端口
    if (bind(g_server.server_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("端口绑定失败");
        close(g_server.server_fd);
        return ERROR;
    }

    // 开始监听
    if (listen(g_server.server_fd, MAX_CLIENTS) < 0) {
        perror("监听失败");
        close(g_server.server_fd);
        return ERROR;
    }

    g_server.is_running = TRUE;
    printf("TCP服务器已启动，监听端口: %d\n", port);

    // 接受客户端连接
    while (g_server.is_running) {
        int client_fd = accept(g_server.server_fd, NULL, NULL);
        if (client_fd == ERROR) {
            if (errno != S_objLib_OBJ_UNAVAILABLE) {
                perror("接受连接失败");
            }
            continue;
        }
//        int flag = 1;
//        setsockopt(client_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(flag));
//    
//        // 调整接收缓冲区大小
//        int recvBufSize = 64 * 1024;  // 64KB
//        setsockopt(client_fd, SOL_SOCKET, SO_RCVBUF, (char*)&recvBufSize, sizeof(recvBufSize));
//    
//        // 调整发送缓冲区大小
//        int sendBufSize = 64 * 1024;  // 64KB
//        setsockopt(client_fd, SOL_SOCKET, SO_SNDBUF, (char*)&sendBufSize, sizeof(sendBufSize));
//    
        // 创建客户端处理任务
        taskSpawn("tcp_client", 100, VX_FP_TASK, 8192, (FUNCPTR)client_handler, 
                 client_fd, 0,0,0,0,0,0,0,0,0);
    }
    return OK;
}

// 停止TCP服务器
void tcp_server_stop() {
    g_server.is_running = FALSE;
    close(g_server.server_fd);
    printf("TCP服务器已停止\n");
}


 
